package org.wattdepot.gdata.kukuicup.updater;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Provides an abstract data type that holds a rolling "window" of timestamped data.
 *  
 * @author Philip Johnson
 */
public class RollingData implements Iterable<RollingData.Entry> {
  /**
   * Data structure holding the entries. 
   * @author Philip Johnson
   */
  public static class Entry {
    /** The last update for this entry. */
    public String lastUpdate;
    /** The data for this entry. */
    public String data;
    /**
     * Creates an entry.
     * @param lastUpdate The last update.
     * @param data The data.
     */
    Entry(String lastUpdate, String data) {
      this.lastUpdate = lastUpdate;
      this.data = data;
    }
  }
  /** Holds the data found so far. */
  private List<RollingData.Entry> entries = new ArrayList<RollingData.Entry>();
  /** The number of data entries to be stored. */
  private int size; 
  
  /**
   * Creates a new RollingData instance and specifies the maximum number of entries. 
   * @param size The size of this RollingData queue of data objects.
   */
  public RollingData(int size) {
    this.size = size;
  }
  
  /**
   * Add a new entry. Typically removes the last entry in the queue when adding this one to keep
   * the size constant.
   * @param lastUpdate The last update value associated with this entry.
   * @param data The data associated with this entry.
   */
  public void add(String lastUpdate, String data) {
    entries.add(0, new RollingData.Entry(lastUpdate, data));
    if (entries.size() > this.size) {
      entries.remove(size);
    }
  }
  
  /**
   * Initializes all entries in the queue to the passed values.
   * @param lastUpdate The lastUpdate for the initial entries. 
   * @param data The data value for the initial entries. 
   */
  public void initialize(String lastUpdate, String data) {
    for (int i = 0; i < size; i++) {
      add(lastUpdate, data);
    }
  }

  /**
   * Allows users to iterate over the entries in this queue using for loop.
   * @return An iterator over the entries.
   */
  @Override
  public Iterator<RollingData.Entry> iterator() {
    return this.entries.iterator();
  }
  
  /**
   * Returns an easy to read version of the queue.
   * @return A string representing the queue.
   */
  @Override 
  public String toString() {
    StringBuffer buff = new StringBuffer();
    for (RollingData.Entry entry : this) {
      buff.append(String.format("[%s, %s]", entry.lastUpdate, entry.data));
    }
    return buff.toString();
  }
  
  /**
   * Returns the timestamp associated with the most recently added entry.
   * @return The most recent timestamp.
   */
  public String getLastTimeStamp() {
    return this.entries.get(0).lastUpdate;
  }
}
